#include "clientToService.h"

#include <sys/time.h>           //  for function ->  gettimeofday(&tval, NULL);

#include <opencv2/opencv.hpp>
#include "json/json.h"          //new version

#include <unistd.h>   //access()
#include <dirent.h>
int showAllFiles( const char * dir_name ,std::vector<std::string> & files);
void findImgsPath(const string &dirPath, std::vector<std::string> &sendImgsPath);
string getLocalTime_self_();
Json::Value heartbeatInit(const std::string robotName);
void matToString(cv::Mat srcImg, string &str, const string imgType);
int json2String(const Json::Value &root, std::string &jsonStr);
Json::Value alarmBeatInit(const string ID, const string AlarmType, const int StartPosition,const int EndPosition,
                        const string AlarmLevel, const int DetailsSize, const string FileName, const string Description, 
                        const string CurrentTime );
Json::Value detectImgBeatInit(const string position, const string FileName);


int main(int argc, char* argv[])
{
    if(argc != 3){
        printf("argc error\n");
        exit(-1);
    }
    const string robotName = argv[1];    //"Robot009";
    ClientToService* text = new ClientToService(robotName, "192.168.1.111", 9999, -1, 50000, "009test");
    thread text_t;
    //text_t = thread(&ClientToService::m_working, text, 5);
    //sleep(2);

    std::string jsonStr;
    Json::Value root, Heart;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    root["ID"] = robotName;
    root["CurentTime"] = getLocalTime_self_();
    Heart["Heartbeat"] = Json::Value(root);

    std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
    jsonWriter->write(Heart, &os);
    jsonStr = os.str();
//*********

    std::vector<std::string> detectImgPaths;
    // "/data3/Robot009/ImageDatas/tempPath_detect/4-23"
    // "/home/user/ljl/imgDatas/111111"

//"/data3/Robot009/ImageDatas/tempPath_detect/5-9"
//"/data3/Robot009/ImageDatas/tempPath_detect/5-9"
    if(access(argv[2], F_OK) != 0){
        printf("%S, this path don't exist\n", argv[2]);
    }
    findImgsPath(argv[2], detectImgPaths);         
    int N = 1;
    while (N--)
    {
    
    for(int i=0; i< detectImgPaths.size(); i++) {
        const string imgPath = detectImgPaths[i]+".jpg"; 
        std::string mapPosition="0";
        const unsigned int idx_1 = imgPath.find("_");
        const unsigned int strSize = imgPath.size();
        if(idx_1 != string::npos && strSize > idx_1+1 && idx_1 != strSize){
            const unsigned int idx_2 = imgPath.find("_", idx_1+1);
            const unsigned int idx_3 = imgPath.rfind("_");
            const string mapID = imgPath.substr(0, idx_1);
            if(idx_2 != string::npos && idx_3 != string::npos && idx_3<strSize && idx_2 < idx_3){
                mapPosition = imgPath.substr(idx_2+1, idx_3 - idx_2 - 1);
            }

        }  

        Json::Value detectInof = detectImgBeatInit(mapPosition, imgPath);
        string detectInof_buf = "null";
        int res = json2String(detectInof, detectInof_buf);
        if (res == -1 || detectInof_buf == "null"){
            std::printf("unalarm json to string error:%d, %s\n",res, "test");
            return -1;
        }
        detectInof_buf = "*****" + detectInof_buf + "#####";
        std::printf("%s\n", detectInof_buf.c_str());

    //**********8
    
        int count = 0;
        
        while (1){
            sleep(1);

            char exit = 'c';
          //  exit = cin.get();
            if(exit == 'q'){
                text->m_setExit(true);
                sleep(1);
                break;
            }
            text->m_sendStr2service(detectInof_buf);
            //text->m_sendStr2service("*****"+jsonStr+"#####");
            std::printf("send info success %d\n", count++);
            break;
        }
        //break;
    }//for
    }//while
    printf("press any key to exit\n");
    cin.get();
    text->m_setExit(true);
    if (text_t.joinable()){
        text_t.join();
    }
    
    delete text;
    text = NULL;

    
    
    std::printf("main exit success\n");
    return 0;
}





string getLocalTime_self_()
{
    // 基于当前系统的当前日期/时间
	time_t now = time(0);

	// 把 now 转换为 tm 结构
	tm *gmtm = localtime(&now);
	//cout << gmtm->tm_year+1900 << "年" << gmtm->tm_mon+1 << "月" << gmtm->tm_mday << "日" << gmtm->tm_hour << ":" << gmtm->tm_min << ":" << gmtm->tm_sec<<endl;

    char buffer[60];
    snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%02d %.2d:%.2d:%.2d", gmtm->tm_year+1900, gmtm->tm_mon+1, gmtm->tm_mday, gmtm->tm_hour,gmtm->tm_min, gmtm->tm_sec);

    string str = buffer;
    return buffer;
}


//dir_name:  dir of mapImage name
//#include <unistd.h>   //access()
//#include <dirent.h>
int showAllFiles( const char * dir_name ,std::vector<std::string> & files)
{
    //need #include <dirent.h>
	// check the parameter !
	if( NULL == dir_name )
	{
		cout<<"showAllFiles:   dir_name is null ! "<<endl;
		return -1;
	}
    if(access(dir_name,00) != 0){ 				// ==0:this path is exit
        perror("mapImage path is faild\n");
        return -1;
	}
	struct dirent * filename;    // return value for readdir()
 	DIR * dir;                   // return value for opendir()
	dir = opendir( dir_name );
	if( NULL == dir )
	{
		std::printf("showAllFiles:  Can not open dir: %s\n", dir_name);
		return -1;
	}

	string file_t;
	/* read all the files in the dir ~ */
	while( ( filename = readdir(dir) ) != NULL )
	{
		// get rid of "." and ".."
		if( strcmp( filename->d_name , "." ) == 0 || 
			strcmp( filename->d_name , "..") == 0    )
			continue;
        
        file_t = dir_name;
        //cout<< file_t + "/" + filename->d_name <<endl;
       // files.push_back(filename -> d_name);
       file_t = filename->d_name;
        //2.获取不带后缀的文件名
	    string name = file_t.substr(0, file_t.rfind("."));
        files.push_back(name);
       // cout<<file_t<<"     "<<name<<endl;
	}
    return 0;
}  

void findImgsPath(const string &dirPath, std::vector<std::string> &sendImgsPath)
{
    showAllFiles((dirPath).c_str(), sendImgsPath);
    return;
}

Json::Value heartbeatInit(const std::string robotName)
{
    std::string jsonStr;
    Json::Value Hear;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    Hear["Heartbeat"]["ID"] = robotName;
    Hear["Heartbeat"]["CurrentTime"] = "xxx";

    // std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
    // jsonWriter->write(Hear, &os);
    // jsonStr = os.str();
    // return jsonStr;

    return Hear;
}
void matToString(cv::Mat srcImg, string &str, const string imgType)
{
    //cv::resize(srcImg, srcImg, cv::Size(round(srcImg.cols * rate), round(srcImg.rows * rate)));

    std::vector<unsigned char> buff;
    cv::imencode(imgType.c_str(), srcImg, buff);
    str.resize(buff.size());
    memcpy(&str[0], buff.data(), buff.size());
}
int json2String(const Json::Value &root, std::string &jsonStr)
{

    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
    if(jsonWriter->write(root, &os) != 0) return -1;
    jsonStr = os.str();
    return 0;
}

Json::Value alarmBeatInit(const string ID, const string AlarmType, const int StartPosition,const int EndPosition,
                        const string AlarmLevel, const int DetailsSize, const string FileName, const string Description, 
                        const string CurrentTime )
{
    std::string jsonStr;
    Json::Value  AlarmInfomation , root;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    AlarmInfomation["ID"] = ID;
    AlarmInfomation["AlarmType"] = AlarmType;
    AlarmInfomation["StartPosition"] = StartPosition;
    AlarmInfomation["EndPosition"] = EndPosition;
    AlarmInfomation["AlarmLevel"] = AlarmLevel;           //"Marjor"
    AlarmInfomation["DetailsSize"] = DetailsSize;
    AlarmInfomation["FileName"] = FileName;
    AlarmInfomation["Description"] = Description;
    AlarmInfomation["CurrentTime"] = CurrentTime;
    AlarmInfomation["Task_ID"] = "";

    root["AlarmInfomation"] = Json::Value(AlarmInfomation);
    return root;
}
Json::Value detectImgBeatInit(const string position, const string FileName)
{
    std::string jsonStr;
    Json::Value  DetectCommand , root;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    DetectCommand["Command"] = "UpdatePic";
    DetectCommand["Args"]["ImageProcessMode"] = "Detect";
    DetectCommand["Args"]["Positions"] = position;
    DetectCommand["Args"]["File_Path"] = FileName;
    DetectCommand["Args"]["Time"] = "2021-06-28 10:37:31";
    DetectCommand["Args"]["Task_ID"] = "";
    
    root["DetectCommand"] = Json::Value(DetectCommand);
    return root;
}















// int sendAlarmToWin(){
//     const string robotName = "Robot001";


//     ClientToService* text = new ClientToService(robotName, "192.168.1.111", 9998, -1, 50000);
//     thread text_t(&ClientToService::m_working, text, 10);
//     sleep(2);

//     std::string jsonStr;
//     Json::Value root, Heart;
//     Json::StreamWriterBuilder writerBuilder;
//     std::ostringstream os;

//     root["ID"] = robotName;
//     root["CurentTime"] = getLocalTime_self_();
//     Heart["Heartbeat"] = Json::Value(root);

//     std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
//     jsonWriter->write(Heart, &os);
//     jsonStr = os.str();

//     cv::Mat testImg = cv::imread("/home/user/ljl/catkin_tcp/socket_part/test/1.jpg");
// //*********
//     string resultImgStr;
//     matToString(testImg, resultImgStr, ".jpg");
//     if(resultImgStr == "null"){
//         std::printf( "m_detect() matToString function error\n");
//         return -1;
//     }
//     Json::Value alarm = alarmBeatInit(robotName, "RailUnusual", 2000 - 1000, 2000 + 1000, "Marjor",  resultImgStr.size(), "name.jpg", "alarm foreign body", "2017-12-14 09:30:23");

//     string alarm_buf = "null";
//     int res = json2String(alarm, alarm_buf);
//     if (res == -1 || alarm_buf == "null"){
//         std::printf("unalarm json to string error:%d, %s\n",res, "test");
//         return -1;
//     }
//     alarm_buf = "*****" + alarm_buf + "#####";
// //**********8
   
//     while (1){
//         char exit = cin.get();
//         text->m_sendStr2service("*****"+jsonStr+"#####");
//         //text->m_sendStr2service(alarm_buf);
//         std::printf("send info success:  img size: %lu\n", resultImgStr.size());
//         if(exit == 'q'){
//             text->m_setExit(true);
//             sleep(1);
//             break;
//         }
//     }

//     text_t.join();
//     delete text;
//     text = NULL;
//     return 0;
// }
